<template>
	<div class="table-box">
		<ProTable ref="proTable" title="角色管理" :columns="columns" :requestApi="getRoleList" selectId="roleId">
			<!-- 表格 header 按钮 -->
			<template #tableHeader="scope">
				<el-button type="primary" :icon="CirclePlus" @click="openDrawer(1)" v-if="isAuth('sys:role:save')">新增</el-button>
				<el-button
					type="danger"
					:icon="Delete"
					plain
					v-if="isAuth('sys:role:delete')"
					@click="batchDelete(scope.selectedListIds as unknown as number[])"
					:disabled="!scope.isSelected"
				>
					批量删除
				</el-button>
			</template>

			<!-- 表格操作 -->
			<template #operation="scope">
				<el-button type="primary" link :icon="EditPen" @click="openDrawer(2, scope.row)" v-if="isAuth('sys:role:update')"
					>编辑</el-button
				>
				<el-button type="danger" link :icon="Delete" @click="deleteAccount(scope.row)" v-if="isAuth('sys:role:delete')"
					>删除</el-button
				>
			</template>
		</ProTable>
		<!-- 新增和编辑 -->
		<zhy-pop-form :drawerTitle="drawerTitle" ref="popRef">
			<template #formbox>
				<form-box :itemForm="itemForm" :submitting="submitting" :closeForm="cancelForm" :submit-form="submitForm" ref="formbox">
					<template #menuIdList>
						<zhy-tree
							:data="treeData"
							node-key="menuId"
							show-checkbox
							default-expand-all
							:highlight-current="true"
							:key="String(defaultCheckedKeys)"
							:defaultProps="defaultProps"
							:default-checked-keys="defaultCheckedKeys"
							@current-change="handleCurrentChange"
							:default-expanded-keys="[-1]"
							@node-click="handleNodeClick"
						></zhy-tree>
					</template>
				</form-box> </template
		></zhy-pop-form>
	</div>
</template>

<script setup lang="tsx" name="role">
import { ref, computed, provide, nextTick, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { ZhyPopForm, ProTable, FormBox, ZhyTree } from '@/components';
import { FromBoxProps } from '@/components/FormBox/interface';
import { ColumnProps } from '@/components/ProTable/interface';
import { useHandleData, useCheckout } from '@/hooks';

import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue';
import { getRoleList, editRole, addRole, deleteRoleBatch, getMenuList, getRoleInfo } from '@/api/modules/sys';
import { buildMenuTreeRecursive, isAuth } from '@/utils/util';

const { getValidRule } = useCheckout();

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const proTable = ref();

const treeData = ref([]);
const menuIdList = ref([]);
const menuRoleList = ref<number[]>([]);
const defaultCheckedKeys = ref<number[]>([]);
const defaultProps = ref({
	children: 'children',
	label: 'name'
});

const handleNodeClick = (node: any) => {
	console.log(node);
};

const handleCurrentChange = (data: any) => {
	menuIdList.value = data.map((item: any) => item.menuId);
	console.log(data);
};

// 表格配置项
const columns: ColumnProps[] = [
	{ type: 'selection', fixed: 'left' },
	{ prop: 'roleId', label: 'ID' },
	{ prop: 'roleName', label: '角色名称', search: { el: 'input' } },
	{
		prop: 'createTime',
		label: '创建时间'
	},
	{
		prop: 'operation',
		label: '操作',
		fixed: 'right',
		isShow: true
	}
];

// 删除用户信息
const deleteAccount = async (params: any) => {
	await useHandleData(deleteRoleBatch, [params?.roleId], `删除【${params.roleName}】`);
	proTable.value.getTableList();
};

// 批量删除(表格组件需要设置selectId)
const batchDelete = async (id: number[]) => {
	await useHandleData(deleteRoleBatch, id, `删除${id.length}条数据`);
	// 清除表格复选框之前选中状态
	proTable.value.clearSelection();
	// 刷新数据
	proTable.value.getTableList();
};

// 打开 drawer(新增、查看、编辑)
const popRef = ref<InstanceType<typeof ZhyPopForm>>();
const formbox = ref<InstanceType<typeof FormBox>>();

const handleType = ref(1);
const drawerTitle = ref<string>('新增');

/**
 * 获取默认选中的菜单
 * @param menuList
 * @returns
 */
const getDefaultCheckedKeys = (menuList: number[]) => {
	const menuIdList = menuList.filter((item: any) => !menuRoleList.value.includes(item));
	console.log(menuIdList, menuRoleList.value);
	return menuIdList;
};

const openDrawer = async (type: number, row?: any) => {
	popRef.value!.visible = true;
	handleType.value = type;
	drawerTitle.value = type === 1 ? '新增' : '编辑';

	// 编辑
	if (type === 2) {
		const { role } = await getRoleInfo(row?.roleId);
		// menuIdList.value = menuList.map((item: any) => item.menuId);
		defaultCheckedKeys.value = getDefaultCheckedKeys(role?.menuIdList);
		console.log(defaultCheckedKeys.value);
		nextTick(() => {
			formbox.value!.formParam = Object.assign(formbox.value!.formParam, {
				...row
			});
		});
	} else {
		defaultCheckedKeys.value = [];
	}
};

// 定义选择菜单弹框展示与否
const dialogVisible = ref(false);
provide('dialogVisible', dialogVisible);

// 提交表单
const submitting = ref(false);

const submitForm = (): void => {
	const params: any = Object.assign(formbox.value!.formParam, {
		menuIdList: menuIdList.value
	});
	// console.log(toRaw(params));
	submitting.value = true;
	// 新增
	if (handleType.value === 1) {
		saveM(params);
	} else {
		// 编辑
		updateM(params);
	}
};

// 取消
const cancelForm = () => {
	popRef.value!.visible = false;
};

const updateM = (params: any): void => {
	editRole({
		...params
	})
		.then(() => {
			ElMessage.success('修改成功');
			submitting.value = false;
			popRef.value!.visible = false;
			proTable.value.getTableList();
		})
		.catch(() => {
			submitting.value = false;
		});
};
const saveM = (params: any): void => {
	addRole({
		...params
	})
		.then(() => {
			ElMessage.success('新增成功');
			submitting.value = false;
			popRef.value!.visible = false;
			proTable.value.getTableList();
		})
		.catch(() => {
			submitting.value = false;
		});
};

const itemForm = computed(() => {
	const itemForm: FromBoxProps[] = [
		// prop 目前不用type字段，会有冲突
		{
			prop: 'roleName',
			label: '角色名称',
			form: { el: 'input', props: { maxlength: 20 } },
			rules: getValidRule({ message: '角色名称' })
		},
		{
			prop: 'remark',
			label: '备注',
			form: { el: 'input', props: {}, defaultValue: '' }
		},

		{
			prop: 'menuIdList',
			label: '菜单权限',
			form: { el: 'checkbox-group', props: {} }
		}
	];
	return itemForm;
});

onMounted(async () => {
	const { menuList } = await getMenuList();
	menuRoleList.value = menuList.filter((item: any) => item.parentId === 1 || !item.parentId).map((item: any) => item.menuId);
	treeData.value = buildMenuTreeRecursive(menuList);
});
</script>
